Ext.define("BioGene.controller.BioGene", {

    extend: "Ext.app.Controller",
    config: {
        refs: {
            searchIndexView: "searchindexview",
            informationView: "informationview",
            searchBox: "#searchField",
            settingsView: "settingsview",
            organismSelect: "#organismSelect",
            geneSelect: "#geneSelect",
            rifSelect: "#rifSelect",
            geneView: "geneview",
            geneViewToolbar: "geneview #geneViewToolbar",
            geneTab: "geneview #geneTab",
            functionTab: "geneview #functionTab",
            referencesTab: "geneview #referencesTab",
            backButton: "geneview #backButton",
            searchButton: "geneview #searchButton",
            pagingBar: "geneview #pagingBar",
            prevButton: "geneview #prevButton",
            nextButton: "geneview #nextButton",
            fontUpButton: "geneview #fontUp",
            fontDownButton: "geneview #fontDown",
            abstractView: "abstractview",
            pubmedLink: "abstractview #pubmedLink",
            abstractClose: "abstractview #abstractCloseButton",
            searchListView: "searchlistview",
            pagingSearchBar: "searchlistview #pagingSearchBar",
            nextSearchButton: "searchlistview #nextSearchButton",
            prevSearchButton: "searchlistview #prevSearchButton",
            searchResultList: "searchlistview #dataList"
        },
        control: {
            searchIndexView: {
                // The commands fired by the search index.
                showInfo: "onShowInfo",
                changeSettings: "onChangeSettings"
            },
            informationView: {
            	indexReturn: "onIndexReturn"
            },
            searchBox: {
                newSearch: "onNewSearch"
            },
            settingsView: {
            	indexCancelReturn: "onSettingsCancel",
            	indexReturn: "onIndexReturn",
            	saveSettings: "onSaveSettings"
            },
            searchButton: {
            	indexReturn: "onSearchIndexReturn"
            },
            backButton: {
            	searchReturn: "onSearchReturn"
            },
            referencesTab: {
            	activateRifPaging: "onActivateRifPaging",
            	disableRifPaging: "onDisableRifPaging",
            	displayAbstract: "onDisplayAbstract"
            },
            nextButton: {
            	activateRifPaging: "onActivateRifPaging"
            },
            prevButton: {
            	activateRifPaging: "onActivateRifPaging"
            },
            abstractClose: {
            	geneReturn: "onGeneReturn"
            },
            nextSearchButton: {
            	nextSearchPage: "onNewSearch"
            },
            prevSearchButton: {
            	nextSearchPage: "onNewSearch"
            },
            searchListView: {
            	indexReturn: "onSearchIndexReturn"
            },
            searchResultList: {
            	loadGene: "displayGene"
            },
            fontUpButton: {
            	fontUp: "onFontUp"
            },
            fontDownButton: {
            	fontDown: "onFontDown"
            }
        }
    },
    
    // Save Settings
    onSaveSettings: function (query) {
    	var settingsView = this.getSettingsView();
    	var settings = settingsView.getValues();
    	setCookie('bg_organism',settings.organism,365);
    	setCookie('bg_references',settings.rifs_per_page,365);
    	setCookie('bg_results',settings.genes_per_page,365);
    	Ext.Msg.alert('Settings', 'Your settings have been saved.', Ext.emptyFn);
    },
    
    // Begin Search
    onNewSearch: function (query, page, direction, ret) {
    	// Set Loading indicator
    	var panel = Ext.getCmp('searchListView');
    	panel.getParent().setMasked({
        	xtype: 'loadmask',
        	message: 'Loading...'
        });
        
        var start = (page * getCookie('bg_results')) - getCookie('bg_results');
    	
    	// Check if search query is empty and return error
    	if (query == '') {
    		panel.getParent().unmask();
    		Ext.Msg.alert('No Results', 'Please enter a search query', Ext.emptyFn);
    	}
    	// Else perform search
    	else {
    		Ext.Ajax.request({
    			url: globalVars.search+'?query='+query+'&org='+getCookie('bg_organism')+'&retstart='+start+'&retmax='+getCookie('bg_results'),
    			scope: this,
    			success: function(response, opts) {
    				panel.getParent().unmask();
    				this.processSearch(response, query, page, direction, ret);
    			},
    			failure: function() {
    				panel.getParent().unmask();
    				Ext.Msg.alert('Error', 'Search Call Failed', Ext.emptyFn);
    			}
    		});
    	}
    	
    },
    
    // Function for processing search response
    processSearch: function (response, query, page, direction, ret) {
    	var jsonText = xml2json(response.responseXML);
		var jsonTextFix = jsonText.replace("undefined","");
		// Fix for json string with single object as store is expecting array (edit json notation slightly to create array of single object)
		if (jsonTextFix.indexOf('"gene_rif":{') != -1) {
			var step1 = jsonTextFix.replace('"gene_rif":{','"gene_rif":[{');
			jsonTextFix = step1.replace('"}}','"}]}');
		}
		if (jsonTextFix.indexOf('"return_code":"SUCCESS","count":"1"') != -1) {
			var step1 = jsonTextFix.replace('"gene_info":{','"gene_info":[{');
			jsonTextFix = step1.replace('}}','}]}');
		}

		var jsonDecode = Ext.JSON.decode(jsonTextFix);
		var jsonData = jsonDecode.biogene_info_list;
		
		// If there is more than 1 result, display search listing
		if(jsonData.count > 1) {
			this.displayResults(jsonData, query, page, direction);
		}
		// If there is exactly one result, display gene page
		else if((jsonData.count == 1) && (jsonData.return_code = "SUCCESS")) {
			this.displayGene(jsonData.gene_info[0], ret);
		}
		else if(jsonData.return_code != "SUCCESS") {
			Ext.Msg.alert('No Results', 'Your search returned no results', Ext.emptyFn);
		}
    },
    
    // Function for displaying search results
    displayResults: function (jsonData, query, page, direction) {
    	var searchListView = this.getSearchListView();
    	var pagingBar = this.getPagingSearchBar();
    	var nextButton = this.getNextSearchButton();
    	var prevButton = this.getPrevSearchButton();
    	var pagingData = new Array();
    				
		// Calculate Pagination Stuff
		pagingData.query = query;
		pagingData.page = page;
		pagingData.start = (page * getCookie("bg_results")) - getCookie("bg_results") + 1;
		if ((page * getCookie("bg_results")) <= jsonData.count) {
			pagingData.end = page * getCookie("bg_results");
		}
		else if ((page * getCookie("bg_results")) > jsonData.count) {
			pagingData.end = (page * getCookie("bg_results"))-((page * getCookie("bg_results"))-jsonData.count);
		}
		if (jsonData.count > (page * getCookie("bg_results"))) {
			nextButton.setHandler( function () {
				this.fireEvent("nextSearchPage", query, page+1, 'left', 'search', this);
			});
			if (nextButton.isHidden()) {
				nextButton.show();
			}
		}
		else if (jsonData.count <= (page * getCookie("bg_results")) && !nextButton.isHidden()){
			nextButton.hide();
		}
		if (page > 1) {
			prevButton.setHandler( function () {
				this.fireEvent("nextSearchPage", query, page-1, 'right', 'search', this);
			});
			if (prevButton.isHidden()) {
				prevButton.show();
			}
		}
		else if (page <= 1 && !prevButton.isHidden()) {
			prevButton.hide();
		}
		
		var rifStore = Ext.getStore("GeneStore");
    	rifStore.setData(jsonData);
    	pagingBar.setTitle(pagingData.start+' - '+pagingData.end+' of '+jsonData.count);
    	Ext.Viewport.animateActiveItem(searchListView, { type: 'slide', direction: direction });
    	if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		} 
    },
    
    // Function for displaying gene view
    displayGene: function (geneInfo, ret) {
    	var geneView = this.getGeneView();
    	this.getGeneTab().setData(geneInfo);
    	this.getFunctionTab().setData(geneInfo);
    	if (ret == "index") {
    		this.getSearchButton().show();
    		this.getBackButton().hide();
    	}
    	else if (ret == "search") {
    		this.getSearchButton().hide();
    		this.getBackButton().show();
    	}
    	
    	// Create array for paging
		var refPaging = new Array();
		refPaging.start = 1;
		refPaging.page = 1;
		refPaging.end = getCookie("bg_references") * refPaging.page;
		
		// Send Data to geneView
		if(!geneInfo.gene_rif) {
			BioGene.view.GeneView.rifArray = new Array();
		}
		else {
			BioGene.view.GeneView.rifArray = geneInfo.gene_rif; // Array of Rigs
		}
    	BioGene.view.GeneView.refPaging = refPaging; // Paging tracking array
    	geneView.setActiveItem(0);
    	this.getGeneViewToolbar().setTitle(geneInfo.gene_symbol);
    	Ext.Viewport.animateActiveItem(geneView, this.slideLeftTransition);
    	if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		}  
    },
    
    // Activate RIF Paging
    onActivateRifPaging: function () {
    	var pagingBar = this.getPagingBar();
    	var nextButton = this.getNextButton();
    	var prevButton = this.getPrevButton();
    	var rifArray = BioGene.view.GeneView.rifArray; // Array of Rifs
    	var refPaging = BioGene.view.GeneView.refPaging; // Array containing Paging Data
    	pagedRifArray = new Array(); // Array to contain current set of Rifs to display
    	
    	var start = refPaging.start - 1;
    	
    	// If array of rifs is empty (no references to display)
    	if (rifArray.length < 1)
    	{
    		if (!pagingBar.isHidden()){
    			pagingBar.hide();
    		}
    		var title = "er";	 // Title for docked toolbar
    	}
    	// Calculate paging stuff
    	else 
    	{
    		// Fix end number if higher than array length
    		if (refPaging.end > rifArray.length)
    		{
    			refPaging.end = rifArray.length;
    		}
    		
    		// Loop through rifArray
			for (var i = start; i < refPaging.end; i++) {
				// Push items onto paged array
				pagedRifArray.push(rifArray[i]);
			}
			
			var title = refPaging.start+' - '+refPaging.end+' of '+rifArray.length; // Title for docked toolbar
			pagingBar.setTitle(title);
			if (pagingBar.isHidden()) {
    			pagingBar.show();
    		}
			
			// Set navigation arrows visible/invisible
			if (refPaging.page > 1 && prevButton.isHidden()) {
				prevButton.show();
			}
			else if (refPaging.page <= 1 && !prevButton.isHidden()){
				prevButton.hide();
			}
			if ((refPaging.page*getCookie("bg_references")) < rifArray.length && nextButton.isHidden()) {
				nextButton.show();
			}
			else if ((refPaging.page*getCookie("bg_references")) >= rifArray.length && !nextButton.isHidden()){
				nextButton.hide();
			}
		}
		
		// Load paged array of Rifs into store for loading into view
		var rifStore = Ext.getStore("GeneRifStore");
    	rifStore.setData(pagedRifArray);
		
		// Set title of bottom toolbar
    },
    
    // Disable RIF PAging
    onDisableRifPaging: function () {
    	var pagingBar = this.getPagingBar();
    	pagingBar.hide();
    },
    
    // Load Abstract Page
    onDisplayAbstract: function (pubmed_id) {
    	var pubmedLink = this.getPubmedLink();
    	var abstractView = this.getAbstractView();
		pubmedLink.setHandler(function(){var a = document.createElement('a'); a.setAttribute('href','http://www.ncbi.nlm.nih.gov/m/pubmed/'+pubmed_id); a.setAttribute('target', '_blank'); var dispatch = document.createEvent("HTMLEvents"); dispatch.initEvent("click", true, true); a.dispatchEvent(dispatch);});
    	
    	var panel = Ext.getCmp('abstractPanel');
        panel.setHtml('');                
        panel.getParent().setMasked({
        	xtype: 'loadmask',
        	message: 'Loading...'
        });
        
        // Ajax request calls for information              
		Ext.Ajax.request({
			url: globalVars.abstract+pubmed_id,
			success: function(response, opts) {
				panel.setHtml(response.responseText);
				panel.getParent().unmask();
				
				var jsonData = Ext.JSON.decode(response.responseText);
    			var extractData = jsonData.PubmedArticleSet.PubmedArticle.MedlineCitation;
    			var abstractData = new Array();
    			
    			abstractData.title = extractData.Article.ArticleTitle;
    			abstractData.affiliation = extractData.Article.Affiliation;
    			
    			// Setup Journal String
    			abstractData.journal = extractData.Article.Journal.ISOAbbreviation.replace(/\./g,'')+'. ';
    			if (extractData.Article.Journal.JournalIssue.PubDate.Year !== undefined)
    				abstractData.journal += extractData.Article.Journal.JournalIssue.PubDate.Year;
    			if (extractData.Article.Journal.JournalIssue.PubDate.Month !== undefined)
    				abstractData.journal += ' '+extractData.Article.Journal.JournalIssue.PubDate.Month;
    			if (extractData.Article.Journal.JournalIssue.PubDate.Day !== undefined)
    				abstractData.journal += ' '+extractData.Article.Journal.JournalIssue.PubDate.Day;
    			abstractData.journal += ';';
    			if (extractData.Article.Journal.JournalIssue.Volume !== undefined)
    				abstractData.journal += extractData.Article.Journal.JournalIssue.Volume;
    			if (extractData.Article.Journal.JournalIssue.Issue !== undefined)
    				abstractData.journal += '('+extractData.Article.Journal.JournalIssue.Issue+')';
    			if (extractData.Article.Pagination.MedlinePgn !== undefined)
    				abstractData.journal += ':'+extractData.Article.Pagination.MedlinePgn;
    			abstractData.journal += '.';
    			if (extractData.Article.ArticleDate !== undefined)
    			{
    				abstractData.journal += ' '+extractData.Article.ArticleDate.DateType;
    				abstractData.journal += ' '+extractData.Article.ArticleDate.Year;
    				if (extractData.Article.ArticleDate.Month == 1)
    					abstractData.journal += ' Jan';
    				else if (extractData.Article.ArticleDate.Month == 2)
    					abstractData.journal += ' Feb';
    				else if (extractData.Article.ArticleDate.Month == 3)
    					abstractData.journal += ' Mar';
    				else if (extractData.Article.ArticleDate.Month == 4)
    					abstractData.journal += ' April';
    				else if (extractData.Article.ArticleDate.Month == 5)
    					abstractData.journal += ' May';
    				else if (extractData.Article.ArticleDate.Month == 6)
    					abstractData.journal += ' June';
    				else if (extractData.Article.ArticleDate.Month == 7)
    					abstractData.journal += ' July';
    				else if (extractData.Article.ArticleDate.Month == 8)
    					abstractData.journal += ' Aug';
    				else if (extractData.Article.ArticleDate.Month == 9)
    					abstractData.journal += ' Sept';
    				else if (extractData.Article.ArticleDate.Month == 10)
    					abstractData.journal += ' Oct';
    				else if (extractData.Article.ArticleDate.Month == 11)
    					abstractData.journal += ' Nov';
    				else if (extractData.Article.ArticleDate.Month == 12)
    					abstractData.journal += ' Dec';
    				abstractData.journal += ' '+extractData.Article.ArticleDate.Day+'.';
    			}
    			
    			// Setup authors string
    			abstractData.authors = '';
    			
    			if (typeof extractData.Article.AuthorList != 'undefined') {
					for (var i = 0; i < extractData.Article.AuthorList.Author.length; i++) 
					{
						abstractData.authors += extractData.Article.AuthorList.Author[i].LastName+' '+extractData.Article.AuthorList.Author[i].Initials;
						if (i < (extractData.Article.AuthorList.Author.length-1))
							abstractData.authors += ', ';
						else if (i = (extractData.Article.AuthorList.Author.length-1))
							abstractData.authors += '.';
					}
				}
				
				// Setup Abstract String
				
				abstractData.abstract = '';
				
				if (typeof extractData.Article.Abstract != 'undefined') {
					if (extractData.Article.Abstract.AbstractText instanceof Array)
					{
						for (var i = 0; i < extractData.Article.Abstract.AbstractText.length; i++) 
						{
							abstractData.abstract += extractData.Article.Abstract.AbstractText[i].Label+': ';
							abstractData.abstract += extractData.Article.Abstract.AbstractText[i].content+' ';
						}
					}
					else
					{
						abstractData.abstract += extractData.Article.Abstract.AbstractText;
					}
					if (extractData.Article.Abstract.CopyrightInformation !== undefined)
						abstractData.abstract += '<br /><br />'+extractData.Article.Abstract.CopyrightInformation;
				}
    				
    			// Setup IDs Array
				
				abstractData.ids = new Array();
				
				if (extractData.OtherID !== undefined) {
					if (extractData.OtherID instanceof Array)
					{
						for (var i = 0; i < extractData.OtherID.length; i++) 
    					{
    						if (extractData.OtherID[i].content.indexOf("PMC") != -1) {
    							var pmcid = 'PMCID: '+ extractData.OtherID[i].content;
    							abstractData.ids.push(pmcid);
    						}
						}
					}
					else 
					{
						if (extractData.OtherID.content.indexOf("PMC") != -1) {
    						var pmcid = 'PMCID: '+ extractData.OtherID.content;
    						abstractData.ids.push(pmcid);
    					}
					}
				}
				
				var pmid = 'PMID: '+extractData.PMID.content+' [PubMed - indexed for '+extractData.Status+']';
				
				abstractData.ids.push(pmid);

    			// Update Abstract view with data and slide up into place
    			abstractView.setData(abstractData);
			},
			failure: function(response, opts) {
				panel.setHtml("Failed to load the information page! Check Ajax Request");
				panel.getParent().unmask();
			}
		});
		Ext.Viewport.animateActiveItem(abstractView, this.slideDownTransition);
		if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		} 
    },
    
    onGeneReturn: function () {
    	
        Ext.Viewport.animateActiveItem(this.getGeneView(), this.slideUpTransition);
        if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		} 
    },
    
    //Change Settings
    onChangeSettings: function () {
    	this.getOrganismSelect().setValue(getCookie("bg_organism"));
    	this.getGeneSelect().setValue(getCookie("bg_results"));
    	this.getRifSelect().setValue(getCookie("bg_references"));
    	Ext.Viewport.animateActiveItem(this.getSettingsView(), this.slideUpTransition);
    	if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		} 
    },
    
    onSettingsCancel: function () {
    	var settingsView = this.getSettingsView();
    	var settings = settingsView.getValues();
    	Ext.Viewport.animateActiveItem(this.getSearchIndexView(), this.slideDownTransition);
    	if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		} 
    },
    
    onFontDown: function (state) {
    	var fontDownButton = this.getFontDownButton();
    	var fontUpButton = this.getFontUpButton();
    	if (fontUpButton.getDisabled() == true) {
    		fontUpButton.enable();
    	}
    	if (state == 'disable') {
    		fontDownButton.disable();
    	}
    },
    
    onFontUp: function (state) {
    	var fontDownButton = this.getFontDownButton();
    	var fontUpButton = this.getFontUpButton();
    	if (fontDownButton.getDisabled() == true) {
    		fontDownButton.enable();
    	}
    	if (state == 'disable') {
    		fontUpButton.disable();
    	}
    },
    
    // Display Information Readme
    onShowInfo: function () {
    	Ext.Viewport.animateActiveItem(this.getInformationView(), this.slideUpTransition);

    	var panel = Ext.getCmp('readme');
        panel.setHtml('');                
        panel.getParent().setMasked({
        	xtype: 'loadmask',
        	message: 'Loading...'
        });
        
        // Ajax request calls for information              
		Ext.Ajax.request({
			url: globalVars.readme,
			success: function(response, opts) {
				panel.setHtml(response.responseText);
				panel.getParent().unmask();
			},
			failure: function(response, opts) {
				panel.setHtml("Failed to load the information page! Check Ajax Request");
				panel.getParent().unmask();
			}
		});
    },
    
    onIndexReturn: function () {
        Ext.Viewport.animateActiveItem(this.getSearchIndexView(), this.slideDownTransition);
        if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		} 
    },
    
    onSearchReturn: function () {
        Ext.Viewport.animateActiveItem(this.getSearchListView(), this.slideRightTransition);
        if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		} 
    },
    
    onSearchIndexReturn: function () {
        Ext.Viewport.animateActiveItem(this.getSearchIndexView(), this.slideRightTransition);
        if(Ext.is.Android) {
     		window.scrollTo(0,1); 
		} 
    },
    
    // Base Class functions.
    launch: function () {
        this.callParent(arguments);
        if (getCookie('bg_font_scale')) {
			var sizeChange = parseInt(getCookie('bg_font_scale'));
			var newSize = adjustPx($("body").css('font-size'),sizeChange);
			$(".fontAdjust").css('font-size',newSize);
		
			var bodySize = parseInt(($("body").css('font-size')).replace("px",""));
    		var panelSize = parseInt(($(".fontAdjust").css('font-size')).replace("px",""));
    		var fontDownButton = this.getFontDownButton();
    		var fontUpButton = this.getFontUpButton();
    		
    		if ((panelSize) == (bodySize+10)) {
				fontUpButton.disable();
			}
    		
    		if ((panelSize) == (bodySize-6)) {
				fontDownButton.disable();
			}
    		
		}
    },
    init: function () {
        this.callParent(arguments);
    },
    getRandomInt: function (min, max) {
    	return Math.floor(Math.random() * (max - min + 1)) + min;
	},
	slideLeftTransition: { type: 'slide', direction: 'left' },
	slideRightTransition: { type: 'slide', direction: 'right' },
	slideUpTransition: { type: 'slide', direction: 'up' },
	slideDownTransition: { type: 'slide', direction: 'down' }

});
